import { throttle } from 'lodash'
import OpenAI from 'openai'

import MessageController from '@/app/controllers/MessageController'
import ThreadController from '@/app/controllers/ThreadController'
import { ChatModelEnum, MessageStatusEnum } from '@/configs/enums'
import { createClient } from '@/utils/supabase/server'

const openai = new OpenAI({
  baseURL: 'https://api.deepseek.com',
  apiKey: process.env.DEEPSEEK_API_KEY,
})

export async function POST(req: Request, res: Response) {
  const supabase = await createClient()
  const { message, model, id } = await req.json()
  try {
    const messageController = new MessageController(supabase)
    const threadController = new ThreadController(supabase)
    console.time('completion')

    const deepseekStream = await openai.chat.completions.create({
      messages: [{ role: 'user', content: message }],
      model: model || ChatModelEnum.DEEPSEEK_CHAT,
      stream: true,
    })

    let threadId = id
    if (!threadId) {
      // create thread
      console.log('create thread')

      threadId = await threadController.createThread(message)
    }

    // create use message
    messageController.createUserMessage(threadId, message)
    // create assistant message
    const messageId = await messageController.createAssistantMessage(threadId)

    const throttleUpdateMessage = throttle((content: string) => {
      messageController.updateMessage(messageId, {
        content,
      })
    }, 300)

    // 流式插入数据库
    const readableStream = new ReadableStream({
      async start(controller) {
        const encoder = new TextEncoder()
        let content = ''

        try {
          for await (const chunk of deepseekStream) {
            const chunkText = chunk.choices[0].delta?.content || ''
            console.log('chunkText', chunkText)
            // update message content
            content += chunkText
            console.log('content======', content)
            throttleUpdateMessage(content)

            // controller.enqueue(encoder.encode(chunkText))
          }
        } catch (error) {
          console.error('Error reading from stream:', error)
          controller.error(error)
        } finally {
          console.log('finally content', content)

          messageController.updateMessage(messageId, {
            content,
            status: MessageStatusEnum.DONE,
          })
          controller.close()
          // update message status
        }
      },
    })

    return Response.json({
      success: true,
      // data:
    })
  } catch (error: any) {
    console.error('Error', error)
    return Response.json({
      success: false,
      message: error.code,
    })
  }
}
